import 'dart:async';

import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter_soundmagus/util.dart';
import 'package:get/get.dart';

export 'package:flutter_soundmagus/util.dart';

const kUUID_Notifys = "49535343-1E4D-4BD9-BA61-23C647249616";
// const kUUID_Writes = ['0000faa1-0000-1000-8000-00805f9b34fb', "49535343-8841-43F4-A8D4-ECBE34729BB3"];
// const kUUID_Services = ['0000faa0-0000-1000-8000-00805f9b34fb', "49535343-FE7D-4AE5-8FA9-9FAFD205E455"];
const kUUID_Writes = ['FAA1'];
const kUUID_Services = ['FAA0'];

class BleHelper {
  //写特征
  BluetoothCharacteristic? _characteristic;
  Stream<List<BluetoothDevice>>? _stream;
  bool connected = false;

  ///蓝牙已连接回调
  void Function(BluetoothDevice device)? onConnect;

  ///蓝牙已断开回调
  VoidCallback? onDisconnect;

  ///数据接收
  void Function(List<int> data)? onReceived;

  static BleHelper _shared = BleHelper._();

  factory BleHelper() {
    return _shared;
  }

  ///可发送判断
  final canSend = false.obs;
  Timer? _canSendTimer;

  ///发送定时
  Timer? _sendSimer;

  List<List<int>> _willSendDatas = [];

  BleHelper._() {
    _canSendTimer = Timer(Duration(seconds: 5), () {
      //TODO: 有其他办法？3秒后渲染完成了才可发数据，避免obx发数据
      _canSendTimer?.cancel();
      canSend.value = true;
    });
    //间隔30ms发送
    _sendSimer = Timer.periodic(Duration(milliseconds: 15), (timer) {
      if (_willSendDatas.isEmpty) return;
      var value = _willSendDatas.removeAt(0);
      _shared._characteristic?.write(value, withoutResponse: true);
    });
    _stream = Stream.periodic(Duration(seconds: 2)).asyncMap((event) => FlutterBluePlus.connectedDevices)
      ..listen((devices) async {
        final device = devices.firstOrNull;
        if (device == null) {
          if (connected) {
            onDisconnect?.call();
          }
          connected = false;
          _characteristic = null;
          print('蓝牙未连接');
          return;
        }
        if (connected) {
          return;
        }

        final services = await device.discoverServices();
        final service =
            services.firstWhereOrNull((element) => kUUID_Services.contains(element.uuid.toString().toUpperCase()));
        if (service == null) {
          return;
        }
        final characteristic = service.characteristics
            .firstWhereOrNull((element) => kUUID_Writes.contains(element.uuid.toString().toUpperCase()));
        if (characteristic != null) {
          _characteristic = characteristic;
          await _characteristic?.setNotifyValue(true);
          _characteristic?.value.listen((event) {
            onReceived?.call(event);
            print('received data: ${event.toHexString()}');
          });

          connected = true;
          onConnect?.call(device);
        }
      });
  }

  ///写入数据
  static void write(List<int>? value) async {
    if (value == null || value.isEmpty || !_shared.canSend.value) {
      return;
    }
    print('willsend: ${value.toHexString()}');
    if (_shared._characteristic != null) {
      _shared._willSendDatas.add(value);
    } else {
      print('ble write not connected');
    }
  }

  ///是否已连接
  static Future<bool> isConnected() async {
    var connectedDevices = await FlutterBluePlus.connectedDevices;
    return connectedDevices.isNotEmpty;
  }
}

void bleWrite(List<int>? value) async {
  return BleHelper.write(value);
}
